package server

import (
	"sync"
)

type EventHandler interface {
	OnSessionOpen(session *RtspSession)
	OnSessionClose(session *RtspSession)

	OnAnnounce(session *RtspSession)
	OnRecord(session *RtspSession)

	OnSetup(session *RtspSession)

	OnDescribe(session *RtspSession)
	OnPlay(session *RtspSession)
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

type dispatchEventHandler struct {
	handles    map[string]EventHandler
	handlesMux sync.Mutex
}

func newDispatchEventHandler() *dispatchEventHandler {
	return &dispatchEventHandler{
		handles: map[string]EventHandler{},
	}
}

func (tis *dispatchEventHandler) AddHandle(id string, h EventHandler) {
	tis.handlesMux.Lock()
	defer tis.handlesMux.Unlock()

	tis.handles[id] = h
}
func (tis *dispatchEventHandler) RemoveHandle(id string) {
	tis.handlesMux.Lock()
	defer tis.handlesMux.Unlock()

	delete(tis.handles, id)
}
func (tis *dispatchEventHandler) getHandles() []EventHandler {
	var handles []EventHandler

	tis.handlesMux.Lock()
	for _, h := range tis.handles {
		handles = append(handles, h)
	}
	tis.handlesMux.Unlock()

	return handles
}

func (tis *dispatchEventHandler) OnSessionOpen(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnSessionOpen(session)
	}
}
func (tis *dispatchEventHandler) OnSessionClose(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnSessionClose(session)
	}
}
func (tis *dispatchEventHandler) OnAnnounce(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnAnnounce(session)
	}
}
func (tis *dispatchEventHandler) OnRecord(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnRecord(session)
	}
}
func (tis *dispatchEventHandler) OnSetup(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnSetup(session)
	}
}
func (tis *dispatchEventHandler) OnDescribe(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnDescribe(session)
	}
}
func (tis *dispatchEventHandler) OnPlay(session *RtspSession) {
	for _, handle := range tis.getHandles() {
		handle.OnPlay(session)
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

type SessionEvent func(session *RtspSession)

type UnimplementedEventHandler struct {
	SessionOpen  SessionEvent
	SessionClose SessionEvent

	Announce SessionEvent
	Record   SessionEvent

	Setup SessionEvent

	Describe SessionEvent
	Play     SessionEvent
}

func (tis *UnimplementedEventHandler) OnSessionOpen(session *RtspSession) {
	if tis.SessionOpen != nil {
		tis.SessionOpen(session)
	}
}
func (tis *UnimplementedEventHandler) OnSessionClose(session *RtspSession) {
	if tis.SessionClose != nil {
		tis.SessionClose(session)
	}
}
func (tis *UnimplementedEventHandler) OnAnnounce(session *RtspSession) {
	if tis.Announce != nil {
		tis.Announce(session)
	}
}
func (tis *UnimplementedEventHandler) OnRecord(session *RtspSession) {
	if tis.Record != nil {
		tis.Record(session)
	}
}
func (tis *UnimplementedEventHandler) OnDescribe(session *RtspSession) {
	if tis.Describe != nil {
		tis.Describe(session)
	}
}
func (tis *UnimplementedEventHandler) OnPlay(session *RtspSession) {
	if tis.Play != nil {
		tis.Play(session)
	}
}
func (tis *UnimplementedEventHandler) OnSetup(session *RtspSession) {
	if tis.Setup != nil {
		tis.Setup(session)
	}
}
